
function LaunchProjectile(origin, target, damage, hiteffect, hitsound, projeffect, projsound, deletein, speed, model)
	local pos, ang = origin:GetBonePosition(origin:LookupBone("ValveBiped.Bip01_R_Hand"))
	local launchProj = ents.Create("rpgdm_proj")
		launchProj:SetPos((pos or origin:EyePos()) + (origin:GetAngles():Forward()*64))
		launchProj.Owner = origin
		launchProj.Target = target
		launchProj.Damage = damage
		launchProj.HitEffect = hiteffect
		launchProj.HitSound = hitsound
		launchProj.TravelEffect = projeffect
		launchProj.TravelSound = projsound
		launchProj.LifeTime = deletein
		if(model != nil)then
			launchProj.NewModel = model
		end
		if(speed != nil)then
			launchProj.ProjSpeed = speed
		end
		launchProj:Spawn()
	return launchProj
end

function CreateTempCompanion(owner, target, damagemin, damagemax, hitsound, hiteffect, idlesound, speed, lifetime, health, model, aggressive)
	local companion = ents.Create("npc_rpgdm")
		companion:SetPos(owner:GetPos()+(owner:GetAngles():Right()*64))
		companion.Owner = owner
		companion.Target = target
		companion.DamageMin = damagemin
		companion.DamageMax = damagemax
		companion.HitEffect = hiteffect
		companion.HitSound = hitsound
		companion.IdleSound = idlesound
		companion.LifeTime = lifetime
		companion.Model = model
		companion.iHealth = health
		companion.Aggressive = aggressive
		companion.IsPet = true
		companion.Speed = speed
		companion:Spawn()
		companion:Activate()
		timer.Simple(lifetime, function() companion:Remove() end)
	return companion
end

function AddEffect(pl, id, effname, mult, add, getfunc, setfunc, dur, maxstacks)
	print("asdasdasdasdasdq")
	for k, v in ipairs(Effects)do
		if(v.effectID == id)then
			local a = v:Init(pl, effname, mult, add, getfunc, setfunc, dur, maxstacks)
			return a
		else
			print("Effect of ID "..id.." not found.")
		end
	end
end

function SpellThink_server()
	for k, v in pairs(player.GetAll()) do
		if(v.Effects != nil)then
			for q, r in pairs(v.Effects)do
				r:Think(v)
				if(r.RemoveMe)then
					table.remove(v.Effects, q)
				end
			end
		end
	
		if(v.DMGMod)then
			DMGMod(v)
		end
		
		if(v.Impact)then
			ImpactThink(v)
		end
	end
	
	for k, v in pairs(ents.FindByClass("npc_rpgdm")) do
		if(v.Effects != nil)then
			for q, r in pairs(v.Effects)do
				r:Think(v)
				if(r.RemoveMe)then
					table.remove(v.Effects, q)
				end
			end
		end
	end
end
hook.Add("Think", "Server Spell Think", SpellThink_server)

function DMGMod(ply)
	if(timer.Exists(""..ply:UniqueID().."DMGMod"))then
		timer.Destroy(""..ply:UniqueID().."DMGMod")
	end
	ply.DMGMod = false
	
	timer.Create(""..ply:UniqueID().."DMGMod", ply.DMGMod_Duration, 1, 
	function()
		ply.DMGMod_Amount = 0
		ply.DMGMod_Duration = 0
	end)
end

function ImpactThink(ply)
		
		ply.ImpactVelocity = ply:GetVelocity():Length()
		
		if(!ply:IsOnGround() and ply.Impact)then
			ply:DoAnimationEvent(ACT_OVERLAY_SHIELD_UP_IDLE)
		end
		
		if (ply:IsOnGround() and ply.Impact)then
			ply:DoAnimationEvent(ACT_OVERLAY_SHIELD_DOWN)
			ParticleEffect( "impact_hit", ply:GetPos(), Angle(0,0,0), nil )
			ply:EmitSound("devin/blackbetty/weapons/Warrior_ShockWave_Area.wav", 100, 100+math.random(-10,10))
			local whirlRadius = ents.FindInSphere(ply:GetPos(), 240)
			for i, s in pairs(whirlRadius)do
			if(s:EntIndex() != ply:EntIndex() and s:IsPlayer() or s:IsNPC() or s:GetClass() == "npc_rpgdm")then
				timer.Simple(0.05, function()
					s:EmitSound("devin/blackbetty/weapons/slam/hit_1.wav", 150, 100+math.random(-10,10))
					ParticleEffect( "pummel_hit", s:GetPos() + Vector(0, 0, 46) + (s:GetAngles():Forward()*6), Angle(0,0,0), ply )
					ParticleEffect( "player_blood", s:GetPos() + Vector(0, 0, 46) + (s:GetAngles():Forward()*6), Angle(0,0,0), ply )
					dmginfo_leap = DamageInfo()
						if(ply.ImpactScale)then
							dmginfo_leap:SetDamage( 10 + math.Round(ply.ImpactVelocity*0.04))
						else
							dmginfo_leap:SetDamage( 15 )
						end
						dmginfo_leap:SetDamageType( DMG_CRUSH ) --Bullet damage
						dmginfo_leap:SetAttacker( ply ) --First player found gets credit
						dmginfo_leap:SetDamageForce( Vector( 0, 0, 1000 ) ) --Launch upwards
					s:SetVelocity(((ply:GetPos() - Vector(0, 0, 30)) - s:GetPos())*-6)
					s:TakeDamageInfo( dmginfo_leap )	
				end)
			end
			ply.Impact = false
			timer.Simple(0.1, function()
				ply:SetNWBool("Casting", false) 
				ply:SetNWBool("Casted", false)
			end)
		end
	end
end

function DamageAvoided(ent, dmg)
	if(ent.Dodge == nil or ent.Parry == nil or ent.Block == nil)then
		if(ent:GetClass() == "npc_rpgdm" or ent:IsNPC() or ent:IsPlayer())then
			ent.Parry = 0.1
			ent.Dodge = 0.1
			ent.Block = 0.0
		end
	end
	local avoidchance = 0
	
	avoidchance = math.Rand(0, 1)
	if(ent.Parry and avoidchance <= ent.Parry)then
		return "Parry"
	end
	avoidchance = math.Rand(0, 1)
	if(ent.Dodge and avoidchance <= ent.Dodge)then
		return "Dodge"
	end
	avoidchance = math.Rand(0, 1)
	if(ent.Block and avoidchance <= ent.Block)then
		return "Block"
	end
	return false
end

function PainSounds( ent, dmg )
	if ( ent:IsPlayer() or ent:GetClass() == "npc_rpgdm" ) then
		amount = dmg:GetDamage()
		if(ent.PainSoundDelay and ent.PainSoundDelay < CurTime())then
			if( amount >= 8 and amount <= 20) then
				ent:EmitSound("devin/blackbetty/player/male/takedamage"..math.random(1,4)..".wav", 140, 100)
			elseif( amount >= 20 ) then
				ent:EmitSound("devin/blackbetty/player/male/takedamagebig"..math.random(1,2)..".wav", 140, 100)
			end
			ent.PainSoundDelay = CurTime() + 0.5
		end
	end
end
hook.Add("EntityTakeDamage", "PainSounds", PainSounds)

function SetPainDelay(ply)
	ply.PainSoundDelay = CurTime() + 1
end
hook.Add("PlayerSpawn", "SetPainDelay", SetPainDelay)

